local upload = require "resty.upload"
local cjson = require "cjson"
local result = require "common.result"

local _M = {
    _VERSION = '0.01'
}

local os_exec = os.execute
local os_date = os.date
local json_encode = cjson.encode
local gsub = string.gsub

local function get_ext(res)
    local ext = 'jpg'
    if res == 'image/png' then
        ext = 'png'
    elseif res == 'image/jpg' or res == 'image/jpeg' then
        ext = 'jpg'
    elseif res == 'image/gif' then
        ext = 'gif'
    end
    return ext
end

local function file_exists(path)
    local file = io.open(path, "rb")
    if file then file:close() end
    return file ~= nil
end

local function json_return(code, message, data)
    ngx.say(json_encode({code = code, msg = message, data = {}}))
end

-- 文件上传
local function uploadfile()
    local args = ngx.req.get_uri_args()
    local filename
    -- 文件保存的根路径
    local saveRootPath = ngx.var.store_dir
    local file_info = {extension = '', filesize = 0, url = '', mime = '' }
    local chunk_size = 4096
    local form, err = upload:new(chunk_size)
    if not form then
        ngx.log(ngx.ERR, "failed to new upload: ", err)
        return nil,  'failed to new upload'
    end

    form:set_timeout(1000)

    -- 字符串 split 分割
    string.split = function(s, p)
        local rt= {}
        string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
        return rt
    end

    -- 支持字符串前后 trim
    string.trim = function(s)
        return (s:gsub("^%s*(.-)%s*$", "%1"))
    end

    -- 保存的文件对象
    local fileToSave

    while true do
        local typ, res, err = form:read()
        if not typ then
            ngx.log(ngx.ERR, "failed to read: " .. err)
            return nil,  'failed to new upload' .. err
        end

        if typ == "header" then
            -- 开始读取 http header
            -- 解析出本次上传的文件名
            local key = res[1]
            local value = res[2]

            if key == "Content-Type" then
                file_info.mime = res[2]
            elseif key == "Content-Disposition" then

                local dir = saveRootPath ..'/'.. os_date('%Y')..'/'..os_date('%m')..'/'..os_date('%d')..'/'
                if file_exists(dir) ~= true then
                    local status = os_exec('mkdir -p '..dir)
                    if status ~= true then
                        return nil, '创建目录失败'
                    end
                end
                -- 解析出本次上传的文件名
                -- form-data; name="testFileName"; filename="testfile.txt"
                filename = ngx.re.match(res[2], '(.+)filename="(.+)"(.*)')
                if filename then
                    filename = filename[2]
                    filename = dir .. filename
                    fileToSave = io.open(filename, "w+")
                    if not fileToSave then
                        ngx.log(ngx.ERR, "failed to open file " .. filename)
                        return nil,  'failed to open file ' .. filename
                    end
                end
            end
        elseif typ == "body" then
            -- 开始读取 http body
            if fileToSave then
                fileToSave:write(res)
            end
        elseif typ == "part_end" then
            -- 文件写结束，关闭文件
            if fileToSave then
                fileToSave:close()
                fileToSave = nil
            end
        elseif typ == "eof" then
            -- 文件读取结束
            filename = gsub(filename, saveRootPath, '')
            file_info.url = filename
            return file_info
        else
            ngx.log(ngx.INFO, "do other things")
        end
    end

        -- ngx.say(cjson.encode(result:success("save file ok")))

        -- local response = '<script type="text/javascript">'
        -- response = response .. 'window.parent.CKEDITOR.tools.callFunction(' .. callback .. ",'" .. "/images/" .. realFileName .. "','')"
        -- response = response .. '</script>'
        -- ngx.header["Content-Type"] = 'text/html;charset=UTF-8'
        -- ngx.say(response)
        -- ngx.log(ngx.ERR, realFileName .. '----------------\n')
end

-- 文件上传
function _M.file()
    local request_method = ngx.var.request_method
    if "POST" ~= request_method then
        json_return(5003, 'not post request method')
    end
    local file_info, err = uploadfile()
    if file_info then
        json_return(200, '上传成功', {imgurl = file_info.url})
    else
        json_return(5003, err)
    end
end

return _M
